package springbootdubbo.filter;

import io.github.resilience4j.ratelimiter.RateLimiter;
import io.github.resilience4j.ratelimiter.RateLimiterConfig;
import io.github.resilience4j.ratelimiter.RateLimiterRegistry;
import io.github.resilience4j.ratelimiter.RequestNotPermitted;
import org.apache.dubbo.rpc.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import springbootdubbo.config.RateLimiterProperties;

import java.time.Duration;


@AutoConfigureAfter(RateLimiterProperties.class)
public class RateLimitFilter implements Filter {
    private static final Logger LOG =   LoggerFactory.getLogger(RateLimitFilter.class);
    static RateLimiter rateLimiter;
    static {
        RateLimiterConfig config=RateLimiterConfig.custom().
                limitForPeriod(RateLimiterProperties.limitForPeriod.intValue()).//每个周期内，允许的请求数
                limitRefreshPeriod(Duration.ofMillis(RateLimiterProperties.limitRefreshPeriod)).//每个周期的时长
                timeoutDuration(Duration.ofMillis(RateLimiterProperties.timeoutDuration)).//被限流时，阻塞等待的时长
                build();
        RateLimiterRegistry rateLimiterRegistry = RateLimiterRegistry.of(config);
        rateLimiter = rateLimiterRegistry.rateLimiter("customBulkhead");
    }
    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
        try {
            RateLimiter.waitForPermission(rateLimiter);
            LOG.info("通过限流执行RPC");
            return invoker.invoke(invocation);
        } catch (RequestNotPermitted rnp) {
            LOG.info("已经限流");
            throw rnp;
        }
    }
}
